var localVideo = document.querySelector('video#localvideo');
var remoteVideo = document.querySelector('video#remotevideo');

var btnConn =  document.querySelector('button#connserver');
var btnLeave = document.querySelector('button#leave');

var offer = document.querySelector('textarea#offer');
var answer = document.querySelector('textarea#answer');


var localStream = null;
var remoteStream = null;

var pc = null;

var roomid = "111111";
var socket = null;

var offerdesc = null;
var state = 'init'; 
function connSignalServer(){
	
	//开启本地视频
	start();

	return true;
}
function start(){

	if(!navigator.mediaDevices ||
		!navigator.mediaDevices.getUserMedia){
		console.error('the getUserMedia is not supported!');
		return;
	}else {  
		navigator.mediaDevices.getDisplayMedia({video:true})
					.then(getMediaStream)
					.catch(handleError);
	}

}

function getMediaStream(stream){
    localStream = stream;
    localVideo.srcObject = stream;
	console.log('bind local media');
    conn();
}
function conn(){

	socket = io.connect();

	socket.on('joined', (roomid, id) => {
		console.log('receive joined message!', roomid, id);
		state = 'joined'

		//如果是多人的话，第一个人不该在这里创建peerConnection
		//都等到收到一个otherjoin时再创建
		//所以，在这个消息里应该带当前房间的用户数
		//
		//create conn and bind media track
		createPeerConnection();
		bindTracks();

		btnConn.disabled = true;
		btnLeave.disabled = false;
		console.log('receive joined message, state=', state);
	});

	socket.on('otherjoin', (roomid) => {
		console.log('receive joined message:', roomid, state);

		//如果是多人的话，每上来一个人都要创建一个新的 peerConnection
		//
		if(state === 'joined_unbind'){
			createPeerConnection();
			bindTracks();
		}

		state = 'joined_conn';
		call();

		console.log('receive other_join message, state=', state);
	});

	socket.on('full', (roomid, id) => {
		console.log('receive full message', roomid, id);
		// hangup();
		// closeLocalMedia();
		socket.disconnect();
		state = 'leaved';
		console.log('receive full message, state=', state);
		alert('the room is full!');
		btnConn.disabled = false;
		btnLeave.disabled = true;
	});

	socket.on('leaved', (roomid, id) => {
		console.log('receive leaved message', roomid, id);
		state='leaved'
		socket.disconnect();
		console.log('receive leaved message, state=', state);

		btnConn.disabled = false;
		btnLeave.disabled = true;
	});

	socket.on('bye', (room, id) => {
		console.log('receive bye message', roomid, id);
		//state = 'created';
		//当是多人通话时，应该带上当前房间的用户数
		//如果当前房间用户不小于 2, 则不用修改状态
		//并且，关闭的应该是对应用户的peerconnection
		//在客户端应该维护一张peerconnection表，它是
		//一个key:value的格式，key=userid, value=peerconnection
		state = 'joined_unbind';
		closePeerConnection();
		// hangup();
		// offer.value = '';
		// answer.value = '';
		console.log('receive bye message, state=', state);
	});

	socket.on('disconnect', (socket) => {
		console.log('receive disconnect message!', roomid);
		// if(!(state === 'leaved')){
		// 	hangup();
		// 	closeLocalMedia();

		// }
		// state = 'leaved';
	
	});

	socket.on('message', (roomid, data) => {
		console.log('receive message!', roomid, data);

		if(data === null || data === undefined){
			console.error('the message is invalid!');
			return;	
		}

		if(data.hasOwnProperty('type') && data.type === 'offer') {
			console.log('receive offer!', data);
			
			offer.value = data.sdp;

			pc.setRemoteDescription(new RTCSessionDescription(data));

			//create answer
			pc.createAnswer()
				.then(getAnswer)
				.catch(err => {
					console.error('Failed to create answer!', err);
				})

		}else if(data.hasOwnProperty('type') && data.type == 'answer'){
			answer.value = data.sdp;
			pc.setRemoteDescription(new RTCSessionDescription(data));
			console.log('receive answer!', data);
		
		}else if (data.hasOwnProperty('type') && data.type === 'candidate'){
			console.log('receive candidate!', data);
			var candidate = new RTCIceCandidate({
				sdpMLineIndex: data.label,
				candidate: data.candidate
			});
			pc.addIceCandidate(candidate);	
		
		}else{
			console.log('the message is invalid!', data);
		
		}
	
	});

 
	socket.emit('join', roomid);

	return true;
}

function bindTracks(){

	console.log('bind tracks into RTCPeerConnection!');

	if( pc === null || pc === undefined) {
		console.error('pc is null or undefined!');
		return;
	}

	if(localStream === null || localStream === undefined) {
		console.error('localstream is null or undefined!');
		return;
	}

	//add all track into peer connection
	localStream.getTracks().forEach((track)=>{
		pc.addTrack(track, localStream);	
	});

}


function createPeerConnection(){
	console.log('create peer connection');
	if(!pc){
		var pcConficg = {
			iceServers: [
				{
					urls: 'turn:49.232.174.112:3478',
					credential: '123456',
					username: 'yangqing'
				}
			]
		};
		pc = new RTCPeerConnection(pcConficg);
		pc.onicecandidate = function(e){
			
			if(e.candidate) {
				sendMessage(roomid, {
					type: 'candidate',
					label:e.candidate.sdpMLineIndex, 
					id:e.candidate.sdpMid, 
					candidate: e.candidate.candidate
				});
			}else{
				console.log('this is the end candidate');
			}
		}
		
		pc.ontrack = getRemoteStream
	}else{
		console.log('peer connection already created!');
	} 
}

function getRemoteStream(e){
	remoteStream = e.streams[0];
	remoteVideo.srcObject = e.streams[0];
}
function call(){
	if(state === 'joined_conn'){
		if(pc){
			var options = {
				offerToReceiveAudio: 1,
				offerToReceiveVideo: 1
			}
			pc.createOffer(options)
				.then(getOffer)
				.catch(handleOfferError);
		}
	}
}
function handleOfferError(err){
	console.error('Failed to create offer!', err);
}

function sendMessage(roomid, data){
	console.log('send p2p message:',roomid, data);
	if(socket){
		socket.emit('message', roomid, data);	
	}
}

function getOffer(desc){
	console.log('get offer');
	pc.setLocalDescription(desc);
	offer.value = desc.sdp;
	sendMessage(roomid,desc);
}

function getAnswer(desc){
	console.log('get answer');
	pc.setLocalDescription(desc);
	answer.value = desc.sdp;
	sendMessage(roomid,desc);
}



function closePeerConnection(){
	console.log('close peer connection');
	if(pc){
		pc.close();
		pc = null;
	}
}

function closeLocalMedia(){
	if(localScream&&localScream.getTracks){
		localScream.getTracks().forEach(track => track.stop());	
	}
	localScream = null;
	
}



function handleError(err){
	console.error('Failed to get Media Stream!', err);
}


function leave(){
	 if(socket){
        socket.emit('leave', '111111');
        
     }
	 closePeerConnection();
	 closeLocalMedia();
     btnConn.disabled = false;
     btnLeave.disabled = true;
}
btnConn.onclick = connSignalServer
btnLeave.onclick = leave;